<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>栈-智能重复</title>
</head>

<body>
  <script>
    /*
      将'3[abc]'转化为'abcabcabc'
      将'3[2[a]2[b]]'转化为'aabbaabbaabb'
    */
    /*
     一个栈存放数字一个栈存放字符串
     遍历每一个字符串，如果是数字那么把数字压栈，把空字符串也压栈
     如果遇到字母就把栈顶这项修改为字母，
     如果这个字符是右大括号那么久将数字弹栈，
     就把字符串栈的暂定的元素重复刚刚的这个次数，弹栈，拼接到新栈顶上
    */
  </script>
  <script>
    function smartRepeat(templateStr) {
      var index = 0,//指针
        stack1 = [],//栈1：存放数字
        stack2 = []//栈2：存放临时字符串
      while (index < templateStr.length - 1 && index < 30) {
        // 剩余部分
        var rest = templateStr.substring(index)
        // 看当前剩余部分是不是以数字和[开头
        if (/^(\d+)\[/.test(rest)) {
          // 得到这个数字
          let times = Number(rest.match(/^(\d+)\[/)[1])
          // 把数字压栈，把空字符串压栈
          stack1.push(times)
          stack2.push('')
          // 让指针后移，times这个数字是几就后移+1位：+1表示后面的[
          index += times.toString().length + 1
        } else if (/^(\w+)\]/.test(rest)) {
          let word = rest.match(/^(\w+)\]/)[1]
          stack2[stack2.length - 1] = word
          // 指针后移
          index += word.length
        } else if (rest[0] === ']') {
          // 如果这个字符是]那么：
          // 1、stack1弹栈
          // 2、stack2弹栈
          // 3、把字符串的新栈顶元素重复刚弹出的那个字符传指定次数拼接到新栈顶上
          let times = stack1.pop()
          let word = stack2.pop()
          stack2[stack2.length - 1] += word.repeat(times)
          index++
        } else {
          index++
        }
      }
      // while循环结束后，stack1和stack2中肯定还有剩余一项，返回如果剩余的个数不对那就是用户问题，方括号没有闭合
      return stack2[0].repeat(stack1[0])
    }
    console.log(smartRepeat('3[1[a]2[b]]'))
  </script>
</body>

</html>